package cn.bluech.lib.utils;

import android.text.TextUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Description: MAC工具类，校验和格式化mac
 * Created by Codeant on 2019/3/19.
 */
public class MacUtils {
    public static final String UNKNOWN_MAC = "FF:FF:FF:FF:FF:FF";
    private static final String MAC_REGEX = "[0-9A-Fa-f]{2}[:-]{0,1}[0-9A-Fa-f]{2}[:-]{0,1}[0-9A-Fa-f]{2}[:-]{0,1}[0-9A-Fa-f]{2}[:-]{0,1}[0-9A-Fa-f]{2}[:-]{0,1}[0-9A-Fa-f]{2}";
    private static final String MAC_REGEX_FORMAT = "[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}";

    /**
     * 检查mac是否符合要求(允许大小写、冒号)
     * 用正则匹配并不高效，会导致界面卡顿问题
     */
    public static boolean check(String mac){
        if(TextUtils.isEmpty(mac)||((mac.length()!=17)&&(mac.length()!=12)))
            return false;

        //return mac.matches(MAC_REGEX);
        boolean haveSep = (mac.length()==17);
        for(int i=0;i<mac.length();i++){
            char value = mac.charAt(i);
            if((haveSep)&&(i%3==2)&&(value==':'))
                continue;
            if((value>='0')&&(value<='9'))
                continue;
            if((value>='A')&&(value<='Z'))
                continue;
            if((value>='a')&&(value<='z'))
                continue;

            return false;
        }

        return true;
    }

    public static boolean isEquals(String mac1, String mac2) {
        if(TextUtils.isEmpty(mac1)){
            return TextUtils.isEmpty(mac2);
        }

        return format(mac1).equals(format(mac2));
    }

    public static boolean isEquals(List<String> list1, List<String> list2){
        if(list1==list2)
            return true;
        if((null==list1)||(null==list2)||(list1.size()!=list2.size()))
            return false;

        list1 = new ArrayList<>(list1);
        list2 = new ArrayList<>(list2);

        Collections.sort(list1);
        Collections.sort(list2);
        for(int i=0;i<list1.size();i++){
            if(!isEquals(list1.get(i),list2.get(i)))
                return false;
        }

        return true;
    }

    /**
     * 未知归属的终端都会放到FF:FF:FF:FF:FF:FF这个虚拟wifi下
     */
    public static boolean isUnknown(String mac){
        return isEquals(mac,UNKNOWN_MAC);
    }

    /**
     * 检查是否mac符合标准格式(严格全部大写+冒号间隔,17字节，用于唯一标识)
     * 这里不使用正则表达式，因为正则匹配消耗的CPU时间是这个的30倍
     * 500次匹配正则需要约120毫秒，手动判断只需4毫秒
     */
    public static boolean isFormat(String raw){
        if(TextUtils.isEmpty(raw)||(raw.length()!=17))
            return false;

        // return raw.matches(MAC_REGEX_FORMAT);
        for(int i=0;i<raw.length();i++){
            char value = raw.charAt(i);
            if((i%3==2)&&(value==':'))
                continue;
            if((value>='0')&&(value<='9'))
                continue;
            if((value>='A')&&(value<='Z'))
                continue;

            return false;
        }

        return true;
    }

    /**
     * 格式化mac字符串(大写用冒号隔开) => AA:BB:CC:DD:EE:FF
     * @param raw 未格式的字符串
     * @return 格式化后的字符串，空字符串表示非法字符无法格式化
     */
    public static String format(String raw){
        if(TextUtils.isEmpty(raw))
            return "";
        if(isFormat(raw))
            return raw;
        // 移除冒号
        raw = raw.replace(":", "").trim();
        if(!check(raw)) // 不合法
            return "";

        return (raw.substring(0, 2) + ':' +
                raw.substring(2, 4) + ':' +
                raw.substring(4, 6) + ':' +
                raw.substring(6, 8) + ':' +
                raw.substring(8, 10) + ':' +
                raw.substring(10, 12))
                .toUpperCase();
    }
}
